<?php
/*
vagapage class
version: 1.0
Author: Will Brubaker http://www.vagabumming.com
Description: pagination is a pain in my ass, so I wrote this to simplify incase I need to use pagination in any of my projects.
Basically, it takes some paramaters, does some calculations and returns an array that can be walked through to generate
paging links.
License: GPL2
*/
/*  Copyright 2011  Will Brubaker  (web: http://www.vagabumming.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License, version 2, as 
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
if(! class_exists('vagapage')){
class vagapage{
/*
the page function takes an array of input numbers and creates an array of pagination values based on those input numbers.
page($arr, $debug = false)
Arguments: $arr - required
	an array(numeric or associative, will be converted to associative beginning with key[0]) consisting of, and in this order:
		$curr an integer representing the current page number - required
		$results an integer representing the total number of results - required
		$limit an integer representing the number of results to display per page - optional, default 10
		$max_links an integer representing the number of links - optional, default 10 but may be re-calculated 
			if out of range.
		$start an integer representing the start - optional, default is 0 or recalculated based on value passed if it is out of range
	$debug, BOOL optional default false.  If true, will return error messages on failure, if false, will exit quietly on failure.
Return Values:
	on success, returns an associative array with $max_links elements (+ any generated next/prev & first/last links) & key/value pairs for each page link.  The keys/values are:
		'disabled' = true if link is to current page, else = false.
		'page_num' the number of the page for the link
			if the number of total pages exceeds the max number of links, first/prev links will be added to the array where 'page_num' is prev/next
			as applicable.  Only outputs these if needed.
			also will create next/last with similar rules
		'result_set' the start number for the link
		
		this array is meant to be used in a foreach statement to output your paging links.
		
	on failure, depending on the reason for failure and whether or not debugging is on of off, will return an array containing the errors or
	will exit quitely, or in the case of $debug being anything other than a boolean, will exit with a message.

in production site, recommended usage is:
require_once('/path/to/vagapage.class.php');
$some_var = new vagapage;
$my_paging_links = $some_var->page($arr);
foreach($my_paging_links as $link){
	output link code
	}
	
on a dev server and using debugging, use some statement to determine whether or not you've reveived a numeric array or associative and output 
appropriately.
*/
function page($arr, $debug = false){
$error = 0;
if(! is_bool($debug)) exit('wrong type of variable passed for $debug.  See documentation');	
if(! is_array($arr)) $error[] = "error # $error++ is: argument passed either empty or is not an array";
$x = count($arr);
if($x > 4) $error[] = "error # $error++ is: you passed too many elements in your array.  Only 4 allowed and you passed $x ";
if(array_keys($arr) != range(0,($x-1)) ){//re-index the array
	foreach($arr as $x){
		$new[] = $x;
		}
		$arr = $new;
		}

for($i = 0; $i < $x; $i++){
	if($i < 1){//our first two variable are mandatory so check them
	if(!isset($arr[$i])) $errors[] = "error # $error++ is current page and limit MUST be passed";//didn't pass the mandatory vars
	}
	if((!empty($arr[$i])) && (!is_int($arr[$i]))) $errors[] = "error # $error++ is: only integer values may be passed in your array";//passed a var, but not an integer
}

//break our vars out:
$curr = $arr[0];
$results = $arr[1];
if(! $arr[2]) $limit = 10;
	else $limit = $arr[2];
if($results <= $limit ){
	if($debug == true) $errors[] = "error # $error++ is:  This isn't really an error, but you've asked to page a result set that doesn't need paging.  i.e. the number of results is less than the limit value";
	else exit;//nothing to do
	}
$totalpages = ceil($results/$limit);

if(! $arr[3]) $max_links = min(($results/$limit),10);
	else $max_links = $arr[3];
	
	if($max_links > $totalpages){
		$max_links = $totalpages;
		if($debug == true) $errors[] = "error # $error++ is: you've asked for more max links than there are total pages";
		}
		
if(! $arr[4]) $start = 0;
	else{
	$start = $arr[4];
	if($start > ($totalpages * $limit)) $errors[] = "error # $error++ is: you've set start to be higher than any possible starting value";
	}
	
/**********
Every check that I can think of is done, math SHOULD work.
**************/

//everything is set up, let's get to work.
if($errors){//something is wrong, the math won't work so exit.  Provide error messages if asked for.
	if($debug == true) return $errors;
	else exit;
}
//do we need anything fancy?
if($totalpages <= $max_links){//no, we don't, just output something and be done with it!
for($i = $start + 1; $i < ($totalpages + 1);$i++){
if($i == $curr) $output[$i]['disabled'] = true;
	else $output[$i]['disabled'] = false;
$output[$i]['page_num'] = ($i);
$output[$i]['result_set'] = (($i * $limit) - $limit);
}//end easy loop
return $output;
}else{
//figure out a start index
$a = floor($max_links/2);
$start_index = $curr - $a;
	if($start_index < 1) $start_index = 1;

while($start_index > ($totalpages - ($max_links - 1))) $start_index--;
//start index is set
$end_index = $start_index + $max_links;

for($i = $start_index; $i < $end_index; $i++){
if($i == $curr) $output[$i]['disabled'] = true;
	else $output[$i]['disabled'] = false;
$output[$i]['page_num'] = $i;
$output[$i]['result_set'] = ($i - 1) * $limit;

}
$prev = array('disabled' => false, 'page_num' => 'prev', 'result_set' => ($curr - 2) * $limit );
$rew = array('disabled' => false, 'page_num' => 'first', 'result_set' => $start);
$next = array('disabled' => false, 'page_num' => 'next', 'result_set' => $curr  * $limit);
$ff = array('disabled' => false, 'page_num' => 'last', 'result_set' => $results - $limit);
if($start_index < $curr ) array_unshift($output,$prev);
if($start_index < $curr - 1 ) array_unshift($output,$rew);
if($curr < $end_index - 1 ) array_push($output,$next);
if($curr < $end_index - 2) array_push($output,$ff);
return $output;


}
}//end page function
}//end class
}//end if class exists
?>